home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MCASM.RAR
/
MC_ASM.EXE
/
WROX_ASM
/
CH9
/
UNERASE
/
UNERASE.ASM
< prev
Wrap
Assembly Source File
|
1994-05-23
|
15KB
|
822 lines
MODEL SMALL
.STACK 100H
.386
EXTRN get_sector:far
EXTRN set_sector:far
.DATA
mes0 db ' Name Ext Attr Status '
mes1 db ' Label $'
mes2 db ' SubDir$'
mes3 db ' $'
mes4 db ' Erased$'
mes5 db 'Input first letter:$'
mes6 db 'Recovered succesfuly$'
mes7 db 'Can not been recovered$'
mes8 db ' $'
mes9 db 'Input drive letter:$'
buffer1 db 1024 dup(?)
buffer2 db 1024 dup(?)
buffer3 db ' '
; FAT
startfat dw ? ; Starting sector of the FAT
endfat dw ? ; Ending sector of the FAT
lengthfat dw ? ; Length of the FAT
fatcnt db ? ; The number of the FATs
fattype db ? ; Type of the FAT
fatpersect dw ? ; the number of FAT's entries per sector
localfatptr dw ? ; Pointer to the FAT's entry
fatsector dw ? ; FAT's sector
fatpreventry dw ? ; Previous entry of the FAT
fatprevsect dw ? ; Previousely read FAT's sector
; ROOT
startroot dd ? ; Starting sector of the root
endroot dd ? ; Ending sector of the root
lengthroot dw ? ; Length of the root
rootpersect dw ? ; The number of the root's entries in a sector
rootsector dd ? ; Already read sector of the root
localrootptr dw ? ; Pointer to the root's entry
; DISK
DRIVENUM dw ? ; Drive number
sectorsize dw ? ; Size of the sector
clustsize dw ? ; Cluster size
startdata dd ? ; Begining sector of the data
; UNERASE
rootentry dw ? ; Offset to the current unerasing file in root
startclust dw ? ; Starting cluster of the file
fileatrib db ? ; File's atribute
filesize dw ? ; File size in clusters
firstchar db '$'
; SCREEN
xcur db ?
ycur db ?
; int25h packet
i25startsec dd ?
i25seccnt dw ?
i25off dw ?
i25seg dw ?
.CODE
mov bx,sp ; Free memory
mov cl,4
shr bx,cl
inc bx
mov ax,ss
add bx,ax
mov ax,es
sub bx,ax
mov ah,4ah
int 21h
jnc @@unerase_010
jmp @@unerase_exit
@@unerase_010: mov ax,@DATA
mov ds,ax
mov ax,0600h ; Clear screen
xor cx,cx
mov dh,24
mov dl,79
mov bh,7
int 10h
call getdrive ; Get drive letter
call initdata ; Initialize data
cmp ax,-1
je @@unerase_exit
@@unerase_020: call screenmenu
cmp ax,1
je @@unerase_exit
call enterchar
call unerase
call message
jmp short @@unerase_020
@@unerase_exit: mov ax,4c00h
int 21h
unerase PROC C NEAR
USES bx,cx,dx,di,es
mov ax,ds
mov es,ax
mov fatprevsect,-1
mov bx,startclust
call getfatentry
cmp ax,0
je @@uner_010
mov ax,-1 ; File can not be recovered
ret
@@uner_010: mov bx,rootentry
mov al,firstchar
mov byte ptr ds:[bx],al
lea ax,buffer1
call FAR PTR set_sector C,DRIVENUM,rootsector,ax,ds,1
mov al,fileatrib ; SubDir
test al,10h
je @@uner_020
inc word ptr filesize
@@uner_020:
mov cx,filesize ; File size in clusters
cmp cx,0 ; File have 0 bytes length
jne @@uner_030
xor ax,ax
ret
@@uner_030: dec cx
; Unerasing loop.
mov bx,startclust ; Starting cluster
mov fatpreventry,bx
@@uner_050: call getfatentry ; Return the FAT's entry in AX, load
; the next sector of the FAT if it
; unnecessary. DX=-1 if end of the FAT
cmp ax,0 ; Free entry
je @@uner_060
inc bx ; Next cluster
jmp short @@uner_050
@@uner_060: cmp cx,0
je @@uner_070
mov ax,fatpreventry
call setfatentry C,0,ax,bx ; Set next cluster in chain
mov fatpreventry,bx
inc bx
dec cx
jmp short @@uner_050
@@uner_070: mov ax,fatpreventry
call setfatentry C,0,ax,bx
call setfatentry C,1,bx,0 ; Last cluster in chain
xor ax,ax
ret
getfatentry PROC
push di
push cx
mov al,fattype
cmp al,12
jne @@getfat_001
xor edx,edx
mov ax,bx ; 12-bit FAT
mov dx,bx
shr dx,1
add edx,eax
jmp short @@getfat_002
@@getfat_001:
xor edx,edx
mov dx,bx ; 16-bit FAT
shl edx,1
@@getfat_002: push edx
mov ax,dx
shr edx,16
mov cx,sectorsize
div cx
mov di,ax
xor dx,dx
mul cx
shl edx,16
or eax,edx
pop edx
sub edx,eax
mov localfatptr,dx
cmp di,endfat ; End of FAT
je @@getfat_040
cmp di,fatprevsect ; Check for reading from disk
je @@getfat_010
cmp fatprevsect,-1 ; First read
jne @@getfat_005
mov fatprevsect,di
jmp short @@getfat_008
@@getfat_005: ; Save previous sector
xor edx,edx
mov dx,fatprevsect
add dx,startfat
mov fatprevsect,di ; Save sector to the FAT
lea di,buffer2
call set_sector C,DRIVENUM,edx,di,ds,1
@@getfat_008: ; Read next sector
xor edx,edx
mov dx,fatprevsect ; Load 2 sectors from the FAT
add dx,startfat
lea di,buffer2
call get_sector C,DRIVENUM,edx,di,ds,2
@@getfat_010: lea di,buffer2
add di,localfatptr ; Get FAT's entry
mov ax,word ptr es:[di]
mov cl,fattype ; Check FAT type
cmp cl,12
jne @@getfat_030
test bx,1 ; 12-bit FAT
jnz @@getfat_020
and ax,0000111111111111b
jmp short @@getfat_030
@@getfat_020: mov cl,4
shr ax,cl
@@getfat_030: xor dx,dx
pop cx
pop di
ret
@@getfat_040: mov dx,-1
pop cx
pop di
ret
getfatentry ENDP
setfatentry PROC C NEAR
ARG entrytype:word,entrynum:word,nextentry:word
USES bx,cx,di
mov bx,entrynum
mov al,fattype
cmp al,12
jne @@setfat_001
xor edx,edx
xor eax,eax
mov ax,bx ; 12-bit FAT
mov dx,bx
shr edx,1
add edx,eax
jmp short @@setfat_002
@@setfat_001:
mov ax,bx ; 16-bit FAT
movzx edx,bx
shl edx,1
@@setfat_002:
push edx
mov ax,dx
shr edx,16
mov cx,sectorsize
div cx
xor dx,dx
mul cx
shl edx,16
or eax,edx
pop edx
sub edx,eax
mov localfatptr,dx
lea di,buffer2
add di,localfatptr ; Get FAT's entry
cmp entrytype,0
je @@setfat_030
mov ax,0ffffh ; Last chain
mov cl,fattype ; Check FAT's type
cmp cl,12
jne @@setfat_015
test bx,1 ; 12-bit FAT
jnz @@setfat_010
and ax,0000111111111111b
or word ptr ds:[di],ax
jmp short @@setfat_020
@@setfat_010: mov cl,4
shl ax,cl
@@setfat_015: or word ptr ds:[di],ax
@@setfat_020: xor edx,edx
mov dx,fatprevsect ; Write sector
add dx,startfat
lea di,buffer2
call set_sector C,DRIVENUM,edx,di,ds,1
jmp @@setfat_050
@@setfat_030: mov ax,nextentry ; Next chain
mov cl,fattype ; Check FAT's type
cmp cl,12
jne @@setfat_060
test bx,1 ; 12-bit FAT
jnz @@setfat_040
and ax,0000111111111111b
and word ptr ds:[di],1111000000000000b
or word ptr ds:[di],ax
jmp short @@setfat_050
@@setfat_040: mov cl,4
shl ax,cl
and word ptr ds:[di],0000000000001111b
or word ptr ds:[di],ax
@@setfat_050: ret
@@setfat_060: mov word ptr ds:[di],ax ; 16-bit FAT
ret
setfatentry ENDP
unerase ENDP
initdata PROC C NEAR
USES bx,cx,dx,di,si
mov ax,DRIVENUM
mov cx,1
xor dx,dx
lea bx,buffer1
int 25h
pop dx
jnc @@init_000
mov word ptr i25startsec,0
mov word ptr i25startsec+2,0
mov i25seccnt,1
lea ax,buffer1
mov i25off,ax
mov i25seg,ds
mov ax,DRIVENUM
mov cx,0ffffh
lea bx,i25startsec
int 25h
pop dx
jc @@init_err
@@init_000: lea bx,buffer1
mov ax,word ptr ds:[bx+0bh]
mov sectorsize,ax
mov al,byte ptr ds:[bx+0dh]
xor ah,ah
mov clustsize,ax
mov ax,word ptr ds:[bx+0eh]
mov startfat,ax
mov al,byte ptr ds:[bx+10h]
mov fatcnt,al
mov ax,word ptr ds:[bx+11h]
mov lengthroot,ax
mov ax,word ptr ds:[bx+13h] ; Calculating the type of the
; FAT
cmp ax,0
je @@init_005
xor dx,dx
mov cx,clustsize
div cx
mov cl,12
cmp ax,0ff6h
jbe @@init_010
@@init_005: mov cl,16
@@init_010: mov fattype,cl
mov ax,word ptr ds:[bx+16h]
mov lengthfat,ax
add ax,startfat
mov endfat,ax
mov ax,sectorsize ; Calculating the number of the FAT's
; entries per sector
mov cx,8
mul cx
mov cl,fattype
xor ch,ch
div cx
cmp dx,0
je @@init_020
inc ax
@@init_020: mov fatpersect,ax
mov ax,lengthfat ; Calculating the begin
; sector of the ROOT
mov cl,fatcnt
xor ch,ch
mul cx
add ax,startfat
mov word ptr startroot,ax
mov word ptr startroot+2,0
mov word ptr rootsector,ax
mov word ptr rootsector+2,0
mov word ptr startdata,ax
mov word ptr startdata+2,0
mov ax,sectorsize ; Calculating the number of the root
; entries per sector
mov cx,32
div cx
mov rootpersect,ax
xor eax,eax
mov ax,lengthroot ; Calculating the ending root's sector
mov cx,32
mul cx
mov cx,sectorsize
div cx
cmp dx,0
je @@init_030
inc ax
@@init_030: mov endroot,eax
add startdata,eax
mov localfatptr,0
mov localrootptr,0
xor ax,ax
ret
@@init_err: mov ax,-1
ret
initdata ENDP
screenmenu PROC C NEAR
USES bx,cx,dx,bp,es
; Return AX=: 1 - exit, 0 - unerase data prepared.
@@scr_000: mov xcur,1
mov ycur,1
lea bx,buffer1
call FAR PTR get_sector C,DRIVENUM,rootsector,bx,ds,1
; Display files
mov ax,ds
mov es,ax
mov ax,1300h
mov bx,63
mov cx,29
xor dx,dx
lea bp,mes0
int 10h
lea bp,buffer1
mov cx,rootpersect
mov bx,7
mov dh,1
@@scr_010: push cx
mov al,byte ptr es:[bp]
cmp al,0
jne @@scr_0101
push bp
lea bp,buffer3
mov dl,xcur
mov ax,1301h
mov cx,30
int 10h
pop bp
jmp short @@scr_017
; Print the name
@@scr_0101: mov dl,xcur
mov ax,1301h
mov cx,11
int 10h
push dx
mov ah,9
mov al,byte ptr es:[bp+0bh]
cmp al,8
jne @@scr_011
lea dx,mes1
jmp short @@scr_013
@@scr_011: test al,10h
je @@scr_012
lea dx,mes2
jmp short @@scr_013
@@scr_012: lea dx,mes3
@@scr_013: int 21h
lea dx,mes3
mov al,byte ptr es:[bp]
cmp al,0E5h
jne @@scr_014
lea dx,mes4
@@scr_014: int 21h
pop dx
@@scr_017: inc dh
add bp,20h
pop cx
loop @@scr_010
@@scr_020: call clearpointer
call setpointer
@@scr_030: xor ah,ah
int 16h
cmp ah,1 ; Esc
jne @@scr_040
jmp @@scr_exit
@@scr_040: cmp ah,81 ; PgDn
jne @@scr_050
mov eax,startdata
dec eax
cmp eax,rootsector
jbe @@scr_030
inc dword ptr rootsector
jmp @@scr_000
@@scr_050: cmp ah,73 ; PgUp
jne @@scr_060
mov eax,startroot
cmp eax,rootsector
jae @@scr_030
dec dword ptr rootsector
jmp @@scr_000
@@scr_060: cmp ah,80 ; Down
jne @@scr_070
mov ax,rootpersect
cmp al,ycur
jbe @@scr_030
inc byte ptr ycur
jmp @@scr_020
@@scr_070: cmp ah,72 ; Up
jne @@scr_080
mov ax,1 ; !!!!!!!!!!! May be changed !!!!!!!
cmp al,ycur
jae @@scr_030
dec byte ptr ycur
jmp @@scr_020
@@scr_080: cmp ah,28 ; Enter
jne @@scr_030
lea bx,buffer1 ; Prepare data for unerase
mov al,ycur
dec al
xor ah,ah
mov cx,32
mul cx
add bx,ax
mov al,byte ptr ds:[bx]
cmp al,0E5h
jne @@scr_100
mov al,byte ptr ds:[bx+0bh]
mov fileatrib,al ; Atributes of the file
mov ax,word ptr ds:[bx+1ah] ; Starting cluster
mov startclust,ax
mov ax,sectorsize ; Calculating file size in
; clusters
mov cx,clustsize
mul cx
mov cx,ax
mov ax,word ptr ds:[bx+1ch]
mov dx,word ptr ds:[bx+1eh]
div cx
cmp dx,0
je @@scr_090
inc ax
@@scr_090: mov filesize,ax
mov rootentry,bx
xor ax,ax
ret
@@scr_exit: mov ax,1
ret
; SubDir
@@scr_100: mov al,byte ptr ds:[bx+0bh] ; Attribute
test al,10h
jne @@scr_110
jmp @@scr_030
@@scr_110: mov ax,word ptr ds:[bx+1ah]
cmp ax,0
je @@scr_120
; SubDir cluster
sub ax,2 ; ?????????????
mov cx,clustsize
mul cx
mov cl,16
shl edx,cl
or eax,edx
add eax,startdata
mov startroot,eax
mov rootsector,eax
xor edx,edx
mov dx,clustsize
add eax,edx
dec eax
mov endroot,eax
jmp @@scr_000
; ROOT
@@scr_120:
xor eax,eax
mov ax,lengthfat ; Calculating the begin
; sector of the ROOT
mov cl,fatcnt
xor ch,ch
mul cx
add ax,startfat
mov startroot,eax
mov rootsector,eax
mov ax,lengthroot ; Calculating the ending root's sector
mov cx,32
mul cx
mov cx,sectorsize
div cx
cmp dx,0
je @@scr_130
inc ax
@@scr_130: mov endroot,eax
jmp @@scr_000
clearpointer PROC C NEAR ; Local procedure for clear screen
; pointers
USES ax,bx,cx,dx
mov cx,rootpersect
@@clear_010: push cx
mov ah,2
xor bh,bh
mov dh,cl
mov dl,0 ; !!!!!!!!!!!!!!!!!!!
int 10h
mov ah,9
mov al,' '
mov bx,7
mov cx,1
int 10h
pop cx
push cx
mov ah,2
xor bh,bh
mov dh,cl
mov dl,12 ; !!!!!!!!!!!!!!!!!!!
int 10h
mov ah,9
mov al,' '
mov bx,7
mov cx,1
int 10h
pop cx
loop @@clear_010
ret
clearpointer ENDP
setpointer PROC C NEAR ; Local procedure for set screen
; pointer
USES ax,bx,cx,dx
mov ah,2
xor bh,bh
mov dh,ycur
mov dl,0 ; !!!!!!!!!!!!!!!!!!!!
int 10h
mov ah,9
xor bh,bh
mov al,'>'
mov cx,1
mov bl,7
int 10h
mov ah,2
xor bh,bh
mov dh,ycur
mov dl,12 ;!!!!!!!!!!!!!!!!!!!!!!!!!
int 10h
mov ah,9
xor bh,bh
mov al,'<'
mov cx,1
mov bl,7
int 10h
ret
setpointer ENDP
screenmenu ENDP
enterchar PROC C NEAR
USES ax,dx
mov ah,2
xor bh,bh
mov dh,23
mov dl,1
int 10h
mov ah,9
lea dx,mes5
int 21h
xor ah,ah
int 16h
cmp al,97
jb @@enter_020
cmp al,122
ja @@enter_020
@@enter_010: sub al,32
jmp short @@enter_040
@@enter_020: cmp al,160
jb @@enter_030
cmp al,175
jbe @@enter_010
@@enter_030: cmp al,224
jb @@enter_040
cmp al,239
ja @@enter_040
sub al,96
@@enter_040: mov firstchar,al
mov ah,2
xor bh,bh
mov dh,23
mov dl,1
int 10h
mov ah,9
lea dx,mes8
int 21h
ret
enterchar ENDP
message PROC C NEAR
USES ax,bx,dx
cmp ax,-1
je @@mess_010
mov ah,2
xor bh,bh
mov dh,23
mov dl,1
int 10h
mov ah,9
lea dx,mes6
int 21h
jmp short @@mess_exit
@@mess_010: mov ah,2
xor bh,bh
mov dh,23
mov dl,1
int 10h
mov ah,9
lea dx,mes7
int 21h
@@mess_exit: xor ah,ah
int 16h
mov ah,2
xor bh,bh
mov dh,23
mov dl,1
int 10h
mov ah,9
lea dx,mes8
int 21h
ret
message ENDP
getdrive PROC C NEAR
USES bx
mov ah,2
xor bh,bh
mov dh,11
mov dl,28
int 10h
mov ah,9
lea dx,mes9
int 21h
@@drv_010: xor ah,ah
int 16h
cmp al,65
jb @@drv_010
cmp al,90
ja @@drv_020
sub al,65
xor ah,ah
mov DRIVENUM,ax
jmp short @@drv_030
@@drv_020: cmp al,97
jb @@drv_010
cmp al,122
ja @@drv_010
sub al,97
xor ah,ah
mov DRIVENUM,ax
@@drv_030: mov ah,2
xor bh,bh
mov dh,11
mov dl,28
int 10h
mov ah,9
lea dx,mes8
int 21h
ret
getdrive ENDP
END